package org.fixies.factory;

import org.fixies.database.MockJndiDataSourceRegister;
import org.fixies.database.SingleConnectionDataSource;
import org.fixies.database.dbunit.DBSupport;
import org.fixies.resource.*;
import org.fixies.spreadsheet.converter.ConverterFactory;
import org.fixies.spreadsheet.excel.XlsBookLoaderFactory;
import org.fixies.spreadsheet.excel.poi.HSSFBookContext;
import org.fixies.spreadsheet.interpreter.BookContext;
import org.fixies.utils.PropertyManager;

import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * ファクトリデフォルト実装川崎健
 *
 * @author Kawasaki
 */
public class DefaultFactory extends JavaBasedFactory {

    public Object getInstance(String key) {
        // singletonでないものはここで生成
        if (key.equals("bookContext")) {
            return createBookContext();
        }
//		if (key.equals("bookHolder")) {
//			return createBookHolder();
//		}
//		if (key.equals("bookLoaderFactory")) {
//			return createBookLoaderFactory();
//		}
        return super.getInstance(key);
    }

    /**
     * @see org.fixies.factory.JavaBasedFactory#createPool()
     */
    @Override
    protected Map<String, Object> createPool() {
        Map<String, Object> pool = new HashMap<String, Object>();

        pool.put("resourceLoader", createResourceLoader());

        DataSource ds = createDataSource();
        pool.put("dataSource", ds);

        pool.put("dbSupport", createDBSupport(ds));

        pool.put("initializeOnce", createInitializeOnce(ds));

        pool.put("converterFactory", createConverterFactory());
        pool.put("bookLoaderFactory", createBookLoaderFactory());
        return pool;
    }

    protected ConverterFactory createConverterFactory() {
        ConverterFactory factory = new ConverterFactory();
        factory.registerDefault();
        return factory;
    }

    protected Initializer createInitializeOnce(DataSource ds) {
        List<Initializer> initializers = new ArrayList<Initializer>();
        Initializer mockJndi = createMockJndiDataSourceRegister(ds);
        initializers.add(mockJndi);

        InitializeOnce once = new InitializeOnce();
        once.setInitializers(initializers);
        return once;
    }

    protected Initializer createMockJndiDataSourceRegister(DataSource ds) {
        String key = MockJndiDataSourceRegister.class.getSimpleName() + ".ds-name";
        String dataSourceName = PropertyManager.getProperty(key, "java:comp/DS");
        Initializer mockJndi = new MockJndiDataSourceRegister(ds, dataSourceName);
        return mockJndi;
    }

    protected BookContext createBookContext() {
        return new HSSFBookContext();
    }

//	protected BookHolder createBookHolder() {
//		BookHolder bookHolder= new BookHolder();
//		bookHolder.setBookContext((BookContext) getInstance("bookContext"));
//		bookHolder.setResourceLoader((ResourceLoader) getInstance("resourceLoader"));
//		return bookHolder;
//	}

    protected BookLoaderFactory createBookLoaderFactory() {
        BookLoaderFactory f = new XlsBookLoaderFactory();
        f.setResourceLoader(createResourceLoader());
        return f;

    }


    protected ResourceLoader createResourceLoader() {
        String[] dirs = new String[]{"src/test/java"};
        return new RelativePathResourceLoader(dirs);
    }

    protected DataSource createDataSource() {

        String driverClass = PropertyManager.getProperty("db.connection.driver_class");
        String url = PropertyManager.getProperty("db.connection.url");
        String user = PropertyManager.getProperty("db.connection.username");
        String pass = PropertyManager.getProperty("db.connection.password");
        return new SingleConnectionDataSource(driverClass, url, user, pass);
    }

    protected DBSupport createDBSupport(DataSource ds) {
        return new DBSupport(ds);
    }

    public void terminate() throws Exception {
    }

}
